// Copyright 2012 Google Inc. All Rights Reserved.

package com.google.appengine.syncserver.entities;

import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.KeyFactory;

/**
 * Generates keys for entities.
 * 
 * The key hierarchy looks as follows:
 * 
 * <pre>
 *                                  Username
 *              -----------------------+---------------------
 *             |                                            |
 *          Preferences                                 User-Metadata
 * (one of SharedPreferences
 * or PageCache kind)
 *      -------+---------
 *      |                |
 *  Preferences       Shards  
 *   - Metadata
 * </pre>
 */
public class EntityKeyFactory {
  /**
   * Enumerator for all the datastore entity kinds we have
   */
  public static enum PreferencesEntityKind {
    // Entity kind for shared preferences.
    SHARED_PREFERENCES("sp_kind"),

    // Entity kind for request pages.
    REQUEST_PAGE_CACHE("page_cache_kind");

    public final String name;

    private PreferencesEntityKind(String name) {
      this.name = name;
    }
  }

  private static final String USERNAME_ENTITY_KIND = "username_kind";
  private static final String SHARD_ENTITY_KIND = "shard_kind";

  private static final String PREFERENCES_METADATA_ENTITY_KIND = "prefs_metadata_kind";
  private static final String PREFERENCES_METADATA_NAME = "prefs_metadata";

  private static final String USER_METADATA_NAME = "user_metadata_name";
  private static final String USER_METADATA_KIND = "user_metadata_kind";

  public static Key getMetadataEntityKey(
      String username, PreferencesEntityKind kind, String preferencesName) {
    Key prefrencesEntityKey = getPreferencesEntityKey(username, kind, preferencesName);
    return KeyFactory.createKey(
        prefrencesEntityKey, PREFERENCES_METADATA_ENTITY_KIND, PREFERENCES_METADATA_NAME);
  }

  public static Key getShardedEntityKey(
      String username, PreferencesEntityKind kind, String preferencesName, int partNumber) {
    Key prefrencesEntityKey = getPreferencesEntityKey(username, kind, preferencesName);
    return KeyFactory.createKey(
        prefrencesEntityKey, SHARD_ENTITY_KIND, Integer.toString(partNumber));
  }

  /**
   * @param username
   * @return user metadata key.
   */
  public static Key getUserMetadataKey(String username) {
    return KeyFactory.createKey(
        getUsernameEntityKey(username), USER_METADATA_KIND, USER_METADATA_NAME);
  }

  private static Key getPreferencesEntityKey(
      String username, PreferencesEntityKind kind, String preferencesName) {
    return KeyFactory.createKey(getUsernameEntityKey(username), kind.name, preferencesName);
  }

  private static Key getUsernameEntityKey(String username) {
    return KeyFactory.createKey(USERNAME_ENTITY_KIND, username);
  }
}
